<?php


namespace api\behaviors\controllers;

use filsh\yii2\oauth2server\filters\auth\CompositeAuth;
use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter;
use yii\base\Event;
use yii\data\ActiveDataProvider;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
use yii\filters\Cors;
use yii\filters\RateLimiter;
use yii\helpers\ArrayHelper;
use yii\rest\ActiveController;
use yii\web\Response;


class BaseController extends ActiveController
{

    // 实现分页
    public function actions()
    {
        $actions = parent::actions();
        // unset($actions['index']);
        /*$actions['index'] = [
            'class' => 'yii\rest\IndexAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            'prepareDataProvider' => function($context, $filter){
               return $this->prepareDataProvider($context, $filter);
            }
        ];*/

        /**
         * 系统提供的列表查询接口，简单搜索
         */
        $actions['index'] = [
            'class' => 'api\behaviors\actions\IndexAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            'dataFilter' => [
                'class' => 'yii\data\ActiveDataFilter',
                'searchModel' => $this->modelClass
            ],
        ];

        /**
         * 自定义的列表查询接口，复杂搜索
         */
        $actions['list'] = [
            'class' => 'api\behaviors\actions\CustomIndexAction',//复杂搜索
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            'dataFilter' => [
                'class' => 'yii\data\ActiveDataFilter',
                'searchModel' => $this->modelClass
            ],
        ];

        /**
         * 自定义的列表查询接口，复杂搜索
         */
        $actions['listu'] = [
            'class' => 'api\behaviors\actions\CustomUserIndexAction',//复杂搜索
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            'dataFilter' => [
                'class' => 'yii\data\ActiveDataFilter',
                'searchModel' => $this->modelClass
            ],
        ];


        /**
         * 系统接口，获取详情
         */
        $actions['view'] = [
            'class' => 'yii\rest\ViewAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
        ];

        /**
         * 自定义的根据多个条件获取一条记录的接口
         */
        $actions['info'] = [
            'class' => 'api\behaviors\actions\ViewAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
        ];

        /**
         * 创建接口
         */
        $actions['create'] = [
            'class' => 'api\behaviors\actions\CreateAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            // 'scenario' => $this->createScenario,
            'scenario' => 'create',
        ];

        /**
         * 更新接口
         */
        $actions['update'] = [
            'class' => 'yii\rest\UpdateAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
            // 'scenario' => $this->updateScenario,
            'scenario' => 'update',
        ];

        /**
         * 删除接口
         */
        $actions['delete'] = [
            'class' => 'api\behaviors\actions\DeleteAction',
            'modelClass' => $this->modelClass,
            'checkAccess' => [$this, 'checkAccess'],
        ];

        $actions['options'] = [
            'class' => 'yii\rest\OptionsAction',
            'collectionOptions'=> ['GET', 'POST', 'HEAD', 'OPTIONS'], // 允许的资源请求反射光hi['GET','POST']
            'resourceOptions'=> ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], //具体资源允许的请求方式['GET','POST', 'DELETE'],
        ];

        return $actions;
    }

    public function prepareDataProvider($context, $filter){
        $requestParams = \Yii::$app->getRequest()->getBodyParams();
        if (empty($requestParams)) {
            $requestParams = \Yii::$app->getRequest()->getQueryParams();
        }

        /* @var $modelClass \yii\db\BaseActiveRecord */
        $modelClass = $this->modelClass;

        $query = $modelClass::find();
        if (!empty($filter)) {
            $query->andWhere($filter);
        }

        return \Yii::createObject([
            'class' => ActiveDataProvider::className(),
            'query' => $query,
            'pagination' => [
                'params' => $requestParams,
            ],
            'sort' => [
                'params' => $requestParams,
                'enableMultiSort' => true
            ],
        ]);
    }


    /**
     * 设置统一返回值 CSDN
     * @throws \yii\base\InvalidConfigException
     */
    public function init()
    {
        parent::init();
        \Yii::$app->user->enableSession = false;
        \Yii::$app->response->on(Response::EVENT_BEFORE_SEND,function(Event $event){
            /** @var \yii\web\Response $response */
            $response = $event->sender;

            if (!is_string($response->data)) {
                $response->data = [
                    'success' => $response->isSuccessful,
                    'code' => $response->statusCode,
                    'isOk' => true,
                    'msg' => $response->statusText,
                    'data' => $response->data,
                ];
                // $response->statusCode = 200;  TODO 设置该选项导致cors 跨域失败，未解决
            }
        });
    }

    /**
     * 认证
     * @return array|array[]
     */
    public function behaviors()
    {

        $behaviors = parent::behaviors();
        /*$behaviors['rateLimiter'] = [
            'class' => RateLimiter::className(),
            'enableRateLimitHeaders' => true,
        ];*/
        $behaviors['corsFilter'] = [
            'class' => Cors::className(),
            'cors' => [
                'Origin' => ['*'], //  // 不带['*']
                'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
                'Access-Control-Request-Headers' => ['*'],
                'Access-Control-Allow-Credentials' => null,
                'Access-Control-Max-Age' => 86400,
                'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page']

            ]
        ];
        $behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON; // 格式化响应
        return ArrayHelper::merge($behaviors, [
            'authenticator' => [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                    ['class' => HttpBearerAuth::className()],
                    ['class' => QueryParamAuth::className(), 'tokenParam' => 'accessToken'],
                ]
            ],
            'exceptionFilter' => [
                'class' => ErrorToExceptionFilter::className()
            ],
        ]);
    }


}